/// fast input
///
/// # Examples
///
/// ```rust
/// use meth_tools::input;
/// let input = input!();
/// let input = input!("input a string");
/// ```
#[macro_export]
macro_rules! input {
    () => {{
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        buf
    }};
    ($($arg:tt)*) => {{
        println!($($arg)*);
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        buf
    }}
}

/// fast input with trim
///
/// # Examples
///
/// ```rust
/// use meth_tools::input_trim;
/// let input = input_trim!();
/// let input = input_trim!("input a string");
/// ```
#[macro_export]
macro_rules! input_trim {
    () => {{
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        buf.trim().to_string()
    }};
    ($($arg:tt)*) => {{
        println!($($arg)*);
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        buf.trim().to_string()
    }}
}

/// fast input number with parse
///
/// # Examples
///
/// ```should_panic
/// use meth_tools::input_number;
/// let input:f64 = input_number!();
/// let input:i32 = input_number!("input a number");
/// ```
#[macro_export]
macro_rules! input_number{
    () => {{
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        match buf.trim().parse() {
            Ok(n) => n,
            Err(_) => {
                eprintln!("\"{}\" is not a number", buf);
                panic!();
            }
        }
    }};
    ($($arg:tt)*) => {{
        println!($($arg)*);
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        match buf.trim().parse() {
            Ok(n) => n,
            Err(e) => {
                eprintln!("\"{}\" is not a number", buf);
                panic!();
            }
        }
    }}
}

/// fast input numbers with parse split with whitespace
///
/// # Examples
///
/// ```rust
/// use meth_tools::input_numbers;
/// let input:Vec<f64> = input_numbers!();
/// let input:Vec<i32> = input_numbers!("input numbers");
/// ```
#[macro_export]
macro_rules! input_numbers {
    () => {{
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        buf.trim().split_whitespace().map(|num| match num.parse() {
            Ok(n) => n,
            Err(_) => {
                eprintln!("\"{}\" is not a number", num);
                panic!();
            }
        }).collect()
    }};
    ($($arg:tt)*) => {{
        println!($($arg)*);
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        buf.trim().split_whitespace().map(|num| match num.parse() {
            Ok(n) => n,
            Err(_) => {
                eprintln!("\"{}\" is not a number", num);
                panic!();
            }
        }).collect()
    }}
}
